package org.example.Thread.B_Thread;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.*;

/**
 * @className: getCount2
 * @author: 芃
 * @description:
 * @date: 2024/5/13 16:28
 */
/*
 * 一个数组，使用固定线程数的线程池，对数组当中的元素进行分组求和
 * 将线程的值进行合并
 */
public class getCount2 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入线程数：");
        int threadCount = scanner.nextInt();
        //此处采用 数组大小/线程数 得到每个线程累加几个
        int addCount = arr.length / threadCount;//尽量保证整数

        int ret =calculate(arr, addCount,threadCount);
        System.out.println("最终结果为：" + ret);
    }

    private static int calculate(int[] arr, int addCount, int threadCount) {
        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        List<Future<Integer>> futureList = new ArrayList<Future<Integer>>();
        int Index = 0;
        for (int i = 0; i < threadCount; i++) {
            int fromIndex = Index;
            Index+=addCount;
            Callable<Integer> callable = new Callable() {
                @Override
                public Object call() throws Exception {
                    int sum = 0;
                    for (int j = fromIndex; j < fromIndex + addCount; j++) {
                        Thread.sleep(3000);
                        sum += arr[j];
                    }
                    return sum;
                }
            };
            Future<Integer> future = executor.submit(callable);
            futureList.add(future);
        }
        int ret = 0;
        for (Future<Integer> future : futureList) {
            try {
                Integer num = future.get();//如果call方法没执行完，这里会阻塞，等待call方法最终把返回值计算出来
                if (num == null){
                    System.out.println("未执行完");
                }
                System.out.println(num);
                ret += num;
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
        executor.shutdown();
        return ret;
    }
}
